{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "db4ccfed-4c26-447e-9ca1-d1af06432cfc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 忽略警告提示\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    " \n",
    "#导入处理数据包\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import time\n",
    "import psutil"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "eec6de5b-c685-4f27-a0ee-424fbf83a914",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练数据集: (891, 12) 测试数据集: (418, 11)\n"
     ]
    }
   ],
   "source": [
    "#导入数据\n",
    "#训练数据集\n",
    "train = pd.read_csv(\"./train.csv\")\n",
    "#测试数据集\n",
    "test  = pd.read_csv(\"./test.csv\")\n",
    "print ('训练数据集:',train.shape,'测试数据集:',test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "028f5231-f1e6-4eea-93d6-edd4c8738c94",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "合并后的数据集: (1309, 12)\n"
     ]
    }
   ],
   "source": [
    "starttime = time.time()\n",
    "#合并数据集，方便同时对两个数据集进行清洗\n",
    "full = train._append( test , ignore_index = True )\n",
    " \n",
    "print ('合并后的数据集:',full.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6fd927de-fd63-433c-ad40-0b5dac95b988",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1309 entries, 0 to 1308\n",
      "Data columns (total 12 columns):\n",
      " #   Column       Non-Null Count  Dtype  \n",
      "---  ------       --------------  -----  \n",
      " 0   PassengerId  1309 non-null   int64  \n",
      " 1   Survived     891 non-null    float64\n",
      " 2   Pclass       1309 non-null   int64  \n",
      " 3   Name         1309 non-null   object \n",
      " 4   Sex          1309 non-null   object \n",
      " 5   Age          1046 non-null   float64\n",
      " 6   SibSp        1309 non-null   int64  \n",
      " 7   Parch        1309 non-null   int64  \n",
      " 8   Ticket       1309 non-null   object \n",
      " 9   Fare         1308 non-null   float64\n",
      " 10  Cabin        295 non-null    object \n",
      " 11  Embarked     1307 non-null   object \n",
      "dtypes: float64(3), int64(4), object(5)\n",
      "memory usage: 122.8+ KB\n"
     ]
    }
   ],
   "source": [
    "# 查看每一列的数据类型，和数据总数\n",
    "full.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "931406a3-6cff-4a10-80b8-15fb229ca0bc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1309 entries, 0 to 1308\n",
      "Data columns (total 12 columns):\n",
      " #   Column       Non-Null Count  Dtype  \n",
      "---  ------       --------------  -----  \n",
      " 0   PassengerId  1309 non-null   int64  \n",
      " 1   Survived     891 non-null    float64\n",
      " 2   Pclass       1309 non-null   int64  \n",
      " 3   Name         1309 non-null   object \n",
      " 4   Sex          1309 non-null   object \n",
      " 5   Age          1309 non-null   float64\n",
      " 6   SibSp        1309 non-null   int64  \n",
      " 7   Parch        1309 non-null   int64  \n",
      " 8   Ticket       1309 non-null   object \n",
      " 9   Fare         1309 non-null   float64\n",
      " 10  Cabin        295 non-null    object \n",
      " 11  Embarked     1307 non-null   object \n",
      "dtypes: float64(3), int64(4), object(5)\n",
      "memory usage: 122.8+ KB\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "我们发现数据总共有1309行。\n",
    "其中数据类型列：年龄（Age）、船舱号（Cabin）里面有缺失数据：\n",
    "1）年龄（Age）里面数据总数是1046条，缺失了1309-1046=263，缺失率263/1309=20%\n",
    "2）船票价格（Fare）里面数据总数是1308条，缺失了1条数据\n",
    "对于数据类型，处理缺失值最简单的方法就是用平均数来填充缺失值\n",
    "'''\n",
    "#年龄(Age)\n",
    "full['Age']=full['Age'].fillna( full['Age'].mean() )\n",
    "#船票价格(Fare)\n",
    "full['Fare'] = full['Fare'].fillna( full['Fare'].mean() )\n",
    "full.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "905c5482-92b4-4e25-a1bd-3e715c1d0d6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "分类变量Embarked，看下最常见的类别，用其填充\n",
    "'''\n",
    "full['Embarked'].value_counts()\n",
    "'''\n",
    "从结果来看，S类别最常见。我们将缺失值填充为最频繁出现的值：\n",
    "S=英国南安普顿Southampton\n",
    "'''\n",
    "full['Embarked'] = full['Embarked'].fillna( 'S' )\n",
    "\n",
    "#船舱号（Cabin）：查看里面数据长啥样\n",
    "full['Cabin'].head()\n",
    " \n",
    "#缺失数据比较多，船舱号（Cabin）缺失值填充为U，表示未知（Uknow） \n",
    "full['Cabin'] = full['Cabin'].fillna( 'U' )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d200c56a-d122-4d81-ac32-2e1071756404",
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "将性别的值映射为数值\n",
    "男（male）对应数值1，女（female）对应数值0\n",
    "'''\n",
    "sex_mapDict={'male':1,\n",
    "            'female':0}\n",
    "#map函数：对Series每个数据应用自定义的函数计算\n",
    "full['Sex']=full['Sex'].map(sex_mapDict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "682adc42-c547-4c55-896f-a9d615f22c83",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Embarked_C</th>\n",
       "      <th>Embarked_Q</th>\n",
       "      <th>Embarked_S</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Embarked_C  Embarked_Q  Embarked_S\n",
       "0       False       False        True\n",
       "1        True       False       False\n",
       "2       False       False        True\n",
       "3       False       False        True\n",
       "4       False       False        True"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#存放提取后的特征\n",
    "embarkedDf = pd.DataFrame()\n",
    " \n",
    "'''\n",
    "使用get_dummies进行one-hot编码，产生虚拟变量（dummy variables），列名前缀是Embarked\n",
    "'''\n",
    "embarkedDf = pd.get_dummies( full['Embarked'] , prefix='Embarked' )\n",
    "embarkedDf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f378f40e-10f0-4004-8fdc-e4a7db49c433",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Pclass_1</th>\n",
       "      <th>Pclass_2</th>\n",
       "      <th>Pclass_3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Pclass_1  Pclass_2  Pclass_3\n",
       "0     False     False      True\n",
       "1      True     False     False\n",
       "2     False     False      True\n",
       "3      True     False     False\n",
       "4     False     False      True"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,embarkedDf],axis=1)\n",
    " \n",
    "'''\n",
    "因为已经使用登船港口(Embarked)进行了one-hot编码产生了它的虚拟变量（dummy variables）\n",
    "所以这里把登船港口(Embarked)删掉\n",
    "'''\n",
    "full.drop('Embarked',axis=1,inplace=True)\n",
    "'''\n",
    "上面drop删除某一列代码解释：\n",
    "因为drop(name,axis=1)里面指定了name是哪一列，比如指定的是A这一列，axis=1表示按行操作。\n",
    "那么结合起来就是把A列里面每一行删除，最终结果是删除了A这一列.\n",
    "简单来说，使用drop删除某几列的方法记住这个语法就可以了：drop([列名1,列名2],axis=1)\n",
    "'''\n",
    "\n",
    "'''\n",
    "客舱等级(Pclass):\n",
    "1=1等舱，2=2等舱，3=3等舱\n",
    "'''\n",
    "#存放提取后的特征\n",
    "pclassDf = pd.DataFrame()\n",
    " \n",
    "#使用get_dummies进行one-hot编码，列名前缀是Pclass\n",
    "pclassDf = pd.get_dummies( full['Pclass'] , prefix='Pclass' )\n",
    "pclassDf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "58634c02-8c93-428e-b2cc-ec89e1bca030",
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,pclassDf],axis=1)\n",
    " \n",
    "#删掉客舱等级（Pclass）这一列\n",
    "full.drop('Pclass',axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "13cd624a-12a3-464d-aa23-1abb9016b2a8",
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "定义函数：从姓名中获取头衔\n",
    "'''\n",
    "def getTitle(name):\n",
    "    str1=name.split( ',' )[1] #Mr. Owen Harris\n",
    "    str2=str1.split( '.' )[0]#Mr\n",
    "    #strip() 方法用于移除字符串头尾指定的字符（默认为空格）\n",
    "    str3=str2.strip()\n",
    "    return str3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "2067a325-47ad-4903-9235-c23d94828028",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Master</th>\n",
       "      <th>Miss</th>\n",
       "      <th>Mr</th>\n",
       "      <th>Mrs</th>\n",
       "      <th>Officer</th>\n",
       "      <th>Royalty</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Master   Miss     Mr    Mrs  Officer  Royalty\n",
       "0   False  False   True  False    False    False\n",
       "1   False  False  False   True    False    False\n",
       "2   False   True  False  False    False    False\n",
       "3   False  False  False   True    False    False\n",
       "4   False  False   True  False    False    False"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#存放提取后的特征\n",
    "titleDf = pd.DataFrame()\n",
    "#map函数：对Series每个数据应用自定义的函数计算\n",
    "titleDf['Title'] = full['Name'].map(getTitle)\n",
    " \n",
    "'''\n",
    "定义以下几种头衔类别：\n",
    "Officer政府官员\n",
    "Royalty王室（皇室）\n",
    "Mr已婚男士\n",
    "Mrs已婚妇女\n",
    "Miss年轻未婚女子\n",
    "Master有技能的人/教师\n",
    "'''\n",
    "#姓名中头衔字符串与定义头衔类别的映射关系\n",
    "title_mapDict = {\n",
    "                    \"Capt\":       \"Officer\",\n",
    "                    \"Col\":        \"Officer\",\n",
    "                    \"Major\":      \"Officer\",\n",
    "                    \"Jonkheer\":   \"Royalty\",\n",
    "                    \"Don\":        \"Royalty\",\n",
    "                    \"Sir\" :       \"Royalty\",\n",
    "                    \"Dr\":         \"Officer\",\n",
    "                    \"Rev\":        \"Officer\",\n",
    "                    \"the Countess\":\"Royalty\",\n",
    "                    \"Dona\":       \"Royalty\",\n",
    "                    \"Mme\":        \"Mrs\",\n",
    "                    \"Mlle\":       \"Miss\",\n",
    "                    \"Ms\":         \"Mrs\",\n",
    "                    \"Mr\" :        \"Mr\",\n",
    "                    \"Mrs\" :       \"Mrs\",\n",
    "                    \"Miss\" :      \"Miss\",\n",
    "                    \"Master\" :    \"Master\",\n",
    "                    \"Lady\" :      \"Royalty\"\n",
    "                    }\n",
    " \n",
    "#map函数：对Series每个数据应用自定义的函数计算\n",
    "titleDf['Title'] = titleDf['Title'].map(title_mapDict)\n",
    " \n",
    "#使用get_dummies进行one-hot编码\n",
    "titleDf = pd.get_dummies(titleDf['Title'])\n",
    "titleDf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "94eb41c2-9a98-4c38-8eca-e41b9b5b6cc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,titleDf],axis=1)\n",
    " \n",
    "#删掉姓名这一列\n",
    "full.drop('Name',axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "43009351-38d5-4a4d-b5ce-877a62220cfe",
   "metadata": {},
   "outputs": [],
   "source": [
    "#存放客舱号信息\n",
    "cabinDf = pd.DataFrame()\n",
    " \n",
    "# '''\n",
    "# 客场号的类别值是首字母，例如：\n",
    "# C85 类别映射为首字母C\n",
    "# '''\n",
    "full[ 'Cabin' ] = full[ 'Cabin' ].map( lambda c : c[0] )\n",
    " \n",
    "##使用get_dummies进行one-hot编码，列名前缀是Cabin\n",
    "cabinDf = pd.get_dummies( full['Cabin'] , prefix = 'Cabin' )\n",
    " \n",
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,cabinDf],axis=1)\n",
    " \n",
    "#删掉客舱号这一列\n",
    "full.drop('Cabin',axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "10991392-af22-4233-962f-30461b4815af",
   "metadata": {},
   "outputs": [],
   "source": [
    "#删掉船票这一列\n",
    "full.drop('Ticket',axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "a924765c-0660-4ed4-885a-fb84aa4d0f71",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>FamilySize</th>\n",
       "      <th>Family_Single</th>\n",
       "      <th>Family_Small</th>\n",
       "      <th>Family_Large</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   FamilySize  Family_Single  Family_Small  Family_Large\n",
       "0           2              0             1             0\n",
       "1           2              0             1             0\n",
       "2           1              1             0             0\n",
       "3           2              0             1             0\n",
       "4           1              1             0             0"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#存放家庭信息\n",
    "familyDf = pd.DataFrame()\n",
    " \n",
    "# '''\n",
    "# 家庭人数=同代直系亲属数（Parch）+不同代直系亲属数（SibSp）+乘客自己\n",
    "# （因为乘客自己也是家庭成员的一个，所以这里加1）\n",
    "# '''\n",
    "familyDf[ 'FamilySize' ] = full[ 'Parch' ] + full[ 'SibSp' ] + 1\n",
    " \n",
    "# '''\n",
    "# 家庭类别：\n",
    "# 小家庭Family_Single：家庭人数=1\n",
    "# 中等家庭Family_Small: 2<=家庭人数<=4\n",
    "# 大家庭Family_Large: 家庭人数>=5\n",
    "# '''\n",
    "#if 条件为真的时候返回if前面内容，否则返回0\n",
    "familyDf[ 'Family_Single' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if s == 1 else 0 )\n",
    "familyDf[ 'Family_Small' ]  = familyDf[ 'FamilySize' ].map( lambda s : 1 if 2 <= s <= 4 else 0 )\n",
    "familyDf[ 'Family_Large' ]  = familyDf[ 'FamilySize' ].map( lambda s : 1 if 5 <= s else 0 )\n",
    " \n",
    "familyDf.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "83a103a8-b36e-48d8-98ae-8ec96edbdb56",
   "metadata": {},
   "outputs": [],
   "source": [
    "#添加one-hot编码产生的虚拟变量（dummy variables）到泰坦尼克号数据集full\n",
    "full = pd.concat([full,familyDf],axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "0e7acdef-de9f-401d-b9e2-ab1beecb8ded",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Survived         1.000000\n",
       "Mrs              0.344935\n",
       "Miss             0.332795\n",
       "Pclass_1         0.285904\n",
       "Family_Small     0.279855\n",
       "Fare             0.257307\n",
       "Cabin_B          0.175095\n",
       "Embarked_C       0.168240\n",
       "Cabin_D          0.150716\n",
       "Cabin_E          0.145321\n",
       "Cabin_C          0.114652\n",
       "Pclass_2         0.093349\n",
       "Master           0.085221\n",
       "Parch            0.081629\n",
       "Cabin_F          0.057935\n",
       "Royalty          0.033391\n",
       "Cabin_A          0.022287\n",
       "FamilySize       0.016639\n",
       "Cabin_G          0.016040\n",
       "Embarked_Q       0.003650\n",
       "PassengerId     -0.005007\n",
       "Cabin_T         -0.026456\n",
       "Officer         -0.031316\n",
       "SibSp           -0.035322\n",
       "Age             -0.070323\n",
       "Family_Large    -0.125147\n",
       "Embarked_S      -0.149683\n",
       "Family_Single   -0.203367\n",
       "Cabin_U         -0.316912\n",
       "Pclass_3        -0.322308\n",
       "Sex             -0.543351\n",
       "Mr              -0.549199\n",
       "Name: Survived, dtype: float64"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#相关性矩阵\n",
    "corrDf = full.corr() \n",
    "# '''\n",
    "# 查看各个特征与生成情况（Survived）的相关系数，\n",
    "# ascending=False表示按降序排列\n",
    "# '''\n",
    "corrDf['Survived'].sort_values(ascending =False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "66d648cd-a8df-413f-85d8-f9de98471d4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "#特征选择\n",
    "full_X = pd.concat( [titleDf,#头衔\n",
    "                     pclassDf,#客舱等级\n",
    "                     familyDf,#家庭大小\n",
    "                     full['Fare'],#船票价格\n",
    "                     cabinDf,#船舱号\n",
    "                     embarkedDf,#登船港口\n",
    "                     full['Sex']#性别\n",
    "                    ] , axis=1 )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "f52fc024-f93a-4218-a6bc-372b15e4700f",
   "metadata": {},
   "outputs": [],
   "source": [
    "#原始数据集有891行\n",
    "sourceRow=891\n",
    " \n",
    "# '''\n",
    "# sourceRow是我们在最开始合并数据前知道的，原始数据集有总共有891条数据\n",
    "# 从特征集合full_X中提取原始数据集提取前891行数据时，我们要减去1，因为行号是从0开始的。\n",
    "# '''\n",
    "#原始数据集：特征\n",
    "source_X = full_X.loc[0:sourceRow-1,:]\n",
    "#原始数据集：标签\n",
    "source_y = full.loc[0:sourceRow-1,'Survived']   \n",
    " \n",
    "#预测数据集：特征\n",
    "pred_X = full_X.loc[sourceRow:,:]\n",
    "# '''\n",
    "# 上面代码解释：\n",
    "# 891行前面的数据是测试数据集，891行之后的数据是预测数据集。[sourceRow:,:]就是从891行开始到最后一行作为预测数据集\n",
    "# '''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "5619559a-ca9a-4edb-9200-d438bd4ef575",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数据集有多少行: 891\n",
      "原始数据集有多少行: 418\n"
     ]
    }
   ],
   "source": [
    "# '''\n",
    "# 确保这里原始数据集取的是前891行的数据，不然后面模型会有错误\n",
    "# '''\n",
    "#原始数据集有多少行\n",
    "print('原始数据集有多少行:',source_X.shape[0])\n",
    "#预测数据集大小\n",
    "print('原始数据集有多少行:',pred_X.shape[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "f39d127e-4566-4033-94c7-28460e09eac4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "原始数据集特征： (891, 27) 训练数据集特征： (712, 27) 测试数据集特征： (179, 27)\n",
      "原始数据集标签： (891,) 训练数据集标签： (712,) 测试数据集标签： (179,)\n"
     ]
    }
   ],
   "source": [
    "# '''\n",
    "# 从原始数据集（source）中拆分出训练数据集（用于模型训练train），测试数据集（用于模型评估test）\n",
    "# train_test_split是交叉验证中常用的函数，功能是从样本中随机的按比例选取train data和test data\n",
    "# train_data：所要划分的样本特征集\n",
    "# train_target：所要划分的样本结果\n",
    "# test_size：样本占比，如果是整数的话就是样本的数量\n",
    "# '''\n",
    "from sklearn.model_selection import train_test_split\n",
    " \n",
    "#建立模型用的训练数据集和测试数据集\n",
    "train_X, test_X, train_y, test_y = train_test_split(source_X ,\n",
    "                                                    source_y,\n",
    "                                                    train_size=.8)\n",
    " \n",
    "#输出数据集大小\n",
    "print ('原始数据集特征：',source_X.shape, \n",
    "       '训练数据集特征：',train_X.shape ,\n",
    "      '测试数据集特征：',test_X.shape)\n",
    " \n",
    "print ('原始数据集标签：',source_y.shape, \n",
    "       '训练数据集标签：',train_y.shape ,\n",
    "      '测试数据集标签：',test_y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "3d9373c9-ba9f-4d4c-9dd0-48bc11fe18fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 第1步：导入算法\n",
    "\n",
    "# 第2步：创建模型：\n",
    "# 逻辑回归（logisic regression）\n",
    "# from sklearn.linear_model import LogisticRegression\n",
    "# log_model = LogisticRegression()\n",
    " \n",
    "# 随机森林Random Forests Model\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "model = RandomForestClassifier(n_estimators=100)\n",
    " \n",
    "#支持向量机Support Vector Machines\n",
    "#from sklearn.svm import SVC, LinearSVC\n",
    "#svc_model = SVC()\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "fdbf6b5c-1ffb-4f54-96ef-e37218bef96a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前CPU使用率：10.300000%\n",
      "总内存：773288MB\n",
      "可用内存：735351MB\n",
      "已用内存：31460MB\n",
      "内存使用率：4%\n"
     ]
    }
   ],
   "source": [
    "#第3步：训练模型\n",
    "model.fit( train_X , train_y )\n",
    "\n",
    "# 获取CPU使用率\n",
    "cpu_usage = psutil.cpu_percent(interval=1)\n",
    "\n",
    "# 获取RAM使用情况\n",
    "ram_usage = psutil.virtual_memory()\n",
    "\n",
    "print(\"当前CPU使用率：%f%%\" % cpu_usage)\n",
    "print(\"总内存：%dMB\" % (ram_usage.total / 1024 / 1024))\n",
    "print(\"可用内存：%dMB\" % (ram_usage.available / 1024 / 1024))\n",
    "print(\"已用内存：%dMB\" % (ram_usage.used / 1024 / 1024))\n",
    "print(\"内存使用率：%d%%\" % ram_usage.percent)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "55af9097-bd1a-4b4f-b43e-31cda780e5db",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8100558659217877"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 分类问题，score得到的是模型的正确率\n",
    "model.score(test_X , test_y )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "e471d185-05c7-45ab-b4f7-6696b73fcb41",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "召回率等评分\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        died       0.85      0.85      0.85       117\n",
      "    survived       0.73      0.73      0.73        62\n",
      "\n",
      "    accuracy                           0.81       179\n",
      "   macro avg       0.79      0.79      0.79       179\n",
      "weighted avg       0.81      0.81      0.81       179\n",
      "\n",
      "运行时间 1.8255574703216553\n"
     ]
    }
   ],
   "source": [
    "# 随机森林的模型报告\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from sklearn.metrics import roc_curve, auc\n",
    "\n",
    "y_predict = model.predict(test_X)\n",
    "print('召回率等评分')\n",
    "print(classification_report(y_predict, test_y, target_names=['died','survived']))\n",
    "# print('混淆矩阵')\n",
    "# print(confusion_matrix(y_predict, test_y))\n",
    "endtime = time.time()\n",
    "print('运行时间',endtime-starttime)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c70689e0-ccb2-497f-a81c-9c6f055d8f23",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
